home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / C++ / Direct3D / MultiAnimation / AnimationInstance.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-09-27  |  10.0 KB  |  295 lines

  1. //-----------------------------------------------------------------------------
  2. // File: AnimationInstance.cpp
  3. //
  4. // Desc: Implementation of the CAnimaInstance class, which encapsulates a
  5. //       specific animation instance used by the CMultiAnimation library.
  6. //
  7. // Copyright (c) Microsoft Corporation. All rights reserved
  8. //-----------------------------------------------------------------------------
  9.  
  10.  
  11. #include "dxstdafx.h"
  12. #include "MultiAnimation.h"
  13.  
  14.  
  15.  
  16.  
  17. //-----------------------------------------------------------------------------
  18. // Name: CAnimInstance::Setup()
  19. // Desc: Initialize ourselves to use the animation controller passed in. Then
  20. //       initialize the animation controller.
  21. //-----------------------------------------------------------------------------
  22. HRESULT CAnimInstance::Setup( LPD3DXANIMATIONCONTROLLER pAC )
  23. {
  24.     assert( pAC != NULL );
  25.  
  26.     DWORD i, dwTracks;
  27.  
  28.     m_pAC = pAC;
  29.  
  30.     // Start with all tracks disabled
  31.     dwTracks = m_pAC->GetMaxNumTracks();
  32.     for( i = 0; i < dwTracks; ++ i )
  33.         m_pAC->SetTrackEnable( i, FALSE );
  34.  
  35.     return S_OK;
  36. }
  37.  
  38.  
  39.  
  40.  
  41. //-----------------------------------------------------------------------------
  42. // Name: CAnimInstance::UpdateFrame()
  43. // Desc: Recursively walk the animation frame hierarchy and for each frame,
  44. //       transform the frame by its parent, starting with a world transform to
  45. //       place the mesh in world space.  This has the effect of a hierarchical
  46. //       transform over all the frames.
  47. //-----------------------------------------------------------------------------
  48. void CAnimInstance::UpdateFrames( MultiAnimFrame * pFrame, D3DXMATRIX * pmxBase )
  49. {
  50.     assert( pFrame != NULL );
  51.     assert( pmxBase != NULL );
  52.  
  53.     // transform the bone
  54.     D3DXMatrixMultiply( &pFrame->TransformationMatrix,
  55.                         &pFrame->TransformationMatrix,
  56.                         pmxBase );
  57.  
  58.     // transform siblings by the same matrix
  59.     if( pFrame->pFrameSibling )
  60.         UpdateFrames( (MultiAnimFrame *) pFrame->pFrameSibling, pmxBase );
  61.  
  62.     // transform children by the transformed matrix - hierarchical transformation
  63.     if( pFrame->pFrameFirstChild )
  64.         UpdateFrames( (MultiAnimFrame *) pFrame->pFrameFirstChild,
  65.                       &pFrame->TransformationMatrix );
  66. }
  67.  
  68.  
  69.  
  70.  
  71. //-----------------------------------------------------------------------------
  72. // Name: CAnimInstance::DrawFrames()
  73. // Desc: Recursively walk the frame hierarchy and draw each mesh container as
  74. //       we find it.
  75. //-----------------------------------------------------------------------------
  76. void CAnimInstance::DrawFrames( MultiAnimFrame * pFrame )
  77. {
  78.     if( pFrame->pMeshContainer )
  79.         DrawMeshFrame( pFrame );
  80.  
  81.     if( pFrame->pFrameSibling )
  82.         DrawFrames( (MultiAnimFrame *) pFrame->pFrameSibling );
  83.  
  84.     if( pFrame->pFrameFirstChild )
  85.         DrawFrames( (MultiAnimFrame *) pFrame->pFrameFirstChild );
  86. }
  87.  
  88.  
  89.  
  90.  
  91. //-----------------------------------------------------------------------------
  92. // Name: CAnimInstance::DrawMeshFrame()
  93. // Desc: Renders a mesh container.  Here we go through each attribute group
  94. //       and set up the matrix palette for each group by multiplying the
  95. //       bone offsets to its bone transformation.  This gives us the completed
  96. //       bone matrices that can be used and blended by the pipeline.  We then
  97. //       set up the effect and render the mesh.
  98. //-----------------------------------------------------------------------------
  99. void CAnimInstance::DrawMeshFrame( MultiAnimFrame * pFrame )
  100. {
  101.     MultiAnimMC * pMC = (MultiAnimMC *) pFrame->pMeshContainer;
  102.     D3DXMATRIX mx;
  103.  
  104.     if( pMC->pSkinInfo == NULL )
  105.         return;
  106.  
  107.     // get bone combinations
  108.     LPD3DXBONECOMBINATION pBC = ( LPD3DXBONECOMBINATION )( pMC->m_pBufBoneCombos->GetBufferPointer() );
  109.     DWORD dwAttrib, dwPalEntry;
  110.  
  111.     // for each palette
  112.     for( dwAttrib = 0; dwAttrib < pMC->m_dwNumAttrGroups; ++ dwAttrib )
  113.     {
  114.         // set each transform into the palette
  115.         for( dwPalEntry = 0; dwPalEntry < pMC->m_dwNumPaletteEntries; ++ dwPalEntry )
  116.         {
  117.             DWORD dwMatrixIndex = pBC[ dwAttrib ].BoneId[ dwPalEntry ];
  118.             if( dwMatrixIndex != UINT_MAX )
  119.                 D3DXMatrixMultiply( &m_pMultiAnim->m_amxWorkingPalette[ dwPalEntry ],
  120.                                     &( pMC->m_amxBoneOffsets[ dwMatrixIndex ] ),
  121.                                     pMC->m_apmxBonePointers[ dwMatrixIndex ] );
  122.         }
  123.  
  124.         // set the matrix palette into the effect
  125.         m_pMultiAnim->m_pEffect->SetMatrixArray( "amPalette",
  126.                                                  m_pMultiAnim->m_amxWorkingPalette,
  127.                                                  pMC->m_dwNumPaletteEntries );
  128.  
  129.         // we're pretty much ignoring the materials we got from the x-file; just set
  130.         // the texture here
  131.         m_pMultiAnim->m_pEffect->SetTexture( "g_txScene", pMC->m_apTextures[ pBC[ dwAttrib ].AttribId ] );
  132.  
  133.         // set the current number of bones; this tells the effect which shader to use
  134.         m_pMultiAnim->m_pEffect->SetInt( "CurNumBones", pMC->m_dwMaxNumFaceInfls - 1 );
  135.  
  136.         // set the technique we use to draw
  137.         if( FAILED( m_pMultiAnim->m_pEffect->SetTechnique( m_pMultiAnim->m_sTechnique ) ) )
  138.             return;
  139.  
  140.         UINT uiPasses, uiPass;
  141.  
  142.         // run through each pass and draw
  143.         m_pMultiAnim->m_pEffect->Begin( & uiPasses, 0/*D3DXFX_DONOTSAVESTATE*/ );
  144.         for( uiPass = 0; uiPass < uiPasses; ++ uiPass )
  145.         {
  146.             m_pMultiAnim->m_pEffect->BeginPass( uiPass );
  147.             pMC->m_pWorkingMesh->DrawSubset( dwAttrib );
  148.             m_pMultiAnim->m_pEffect->EndPass();
  149.         }
  150.         m_pMultiAnim->m_pEffect->End();
  151.     }
  152. }
  153.  
  154.  
  155.  
  156.  
  157. //-----------------------------------------------------------------------------
  158. // Name: CAnimInstance::CAnimInstance()
  159. // Desc: Constructor of CAnimInstance
  160. //-----------------------------------------------------------------------------
  161. CAnimInstance::CAnimInstance( CMultiAnim * pMultiAnim )
  162. :   m_pMultiAnim( pMultiAnim ),
  163.     m_pAC( NULL )
  164. {
  165.     assert( pMultiAnim != NULL );
  166. }
  167.  
  168.  
  169.  
  170.  
  171. //-----------------------------------------------------------------------------
  172. // Name: CAnimInstance::~CAnimInstance()
  173. // Desc: Destructor of CAnimInstance
  174. //-----------------------------------------------------------------------------
  175. CAnimInstance::~CAnimInstance()
  176. {
  177. }
  178.  
  179.  
  180.  
  181.  
  182. //-----------------------------------------------------------------------------
  183. // Name: CAnimInstance::Cleanup()
  184. // Desc: Performs the cleanup task
  185. //-----------------------------------------------------------------------------
  186. void CAnimInstance::Cleanup()
  187. {
  188.     if( m_pAC )
  189.         m_pAC->Release();
  190. }
  191.  
  192.  
  193.  
  194.  
  195. //-----------------------------------------------------------------------------
  196. // Name: CAnimInstance::GetMultiAnim()
  197. // Desc: Returns the CMultiAnimation object that this instance uses.
  198. //-----------------------------------------------------------------------------
  199. CMultiAnim * CAnimInstance::GetMultiAnim()
  200. {
  201.     return m_pMultiAnim;
  202. }
  203.  
  204.  
  205.  
  206.  
  207. //-----------------------------------------------------------------------------
  208. // Name: CAnimInstance::GetAnimController()
  209. // Desc: Returns the animation controller for this instance.  The caller
  210. //       must call Release() when done with it.
  211. //-----------------------------------------------------------------------------
  212. void CAnimInstance::GetAnimController( LPD3DXANIMATIONCONTROLLER * ppAC )
  213. {
  214.     assert( ppAC != NULL );
  215.     m_pAC->AddRef();
  216.     * ppAC = m_pAC;
  217. }
  218.  
  219.  
  220.  
  221.  
  222. //-----------------------------------------------------------------------------
  223. // Name: CAnimInstance::GetWorldTransform()
  224. // Desc: Returns the world transformation matrix for this animation instance.
  225. //-----------------------------------------------------------------------------
  226. D3DXMATRIX CAnimInstance::GetWorldTransform()
  227. {
  228.     return m_mxWorld;
  229. }
  230.  
  231.  
  232.  
  233. //-----------------------------------------------------------------------------
  234. // Name: CAnimInstance::SetWorldTransform()
  235. // Desc: Sets the world transformation matrix for this instance.
  236. //-----------------------------------------------------------------------------
  237. void CAnimInstance::SetWorldTransform( const D3DXMATRIX * pmxWorld )
  238. {
  239.     assert( pmxWorld != NULL );
  240.     m_mxWorld = * pmxWorld;
  241. }
  242.  
  243.  
  244.  
  245.  
  246. //-----------------------------------------------------------------------------
  247. // Name: CAnimInstance::AdvanceTime()
  248. // Desc: Advance the local time of this instance by dTimeDelta with a
  249. //       callback handler to handle possible callback from the animation
  250. //       controller.  Then propagate the animations down the hierarchy while
  251. //       transforming it into world space.
  252. //-----------------------------------------------------------------------------
  253. HRESULT CAnimInstance::AdvanceTime( DOUBLE dTimeDelta, ID3DXAnimationCallbackHandler * pCH )
  254. {
  255.     HRESULT hr;
  256.  
  257.     // apply all the animations to the bones in the frame hierarchy.
  258.     hr = m_pAC->AdvanceTime( dTimeDelta, pCH );
  259.     if( FAILED( hr ) )
  260.         return hr;
  261.  
  262.     // apply the animations recursively through the hierarchy, and set the world.
  263.     UpdateFrames( m_pMultiAnim->m_pFrameRoot, & m_mxWorld );
  264.  
  265.     return S_OK;
  266. }
  267.  
  268.  
  269.  
  270.  
  271. //-----------------------------------------------------------------------------
  272. // Name: CAnimInstance::ResetTime()
  273. // Desc: Resets the local time for this instance.
  274. //-----------------------------------------------------------------------------
  275. HRESULT CAnimInstance::ResetTime()
  276. {
  277.     return m_pAC->ResetTime();
  278. }
  279.  
  280.  
  281.  
  282.  
  283. //-----------------------------------------------------------------------------
  284. // Name: CAnimInstance::Draw()
  285. // Desc: Renders the frame hierarchy of our CMultiAnimation object.  This is
  286. //       normally called right after AdvanceTime() so that we render the
  287. //       mesh with the animation for this instance.
  288. //-----------------------------------------------------------------------------
  289. HRESULT CAnimInstance::Draw()
  290. {
  291.     DrawFrames( m_pMultiAnim->m_pFrameRoot );
  292.  
  293.     return S_OK;
  294. }
  295.